import * as $array from "./06-Array";

export type Listener = (now: number) => void;

let pendingFrame = false;

const nextQueue: Array<Listener> = [];
const readQueue: Array<Listener> = [];
const writeQueue: Array<Listener> = [];
const idleQueue: Array<Listener> = []; //空闲队列

const fps = 1000 / 60;

// https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame
// https://www.jianshu.com/p/fa5512dfb4f5
// 请求动画帧 函数
export const raf =
  typeof requestAnimationFrame === "function"
    ? function (fn: () => void): void {
        requestAnimationFrame(fn);
      }
    : function (fn: () => void): void {
        setTimeout(fn, fps);
      };

//   帧循环
function frameLoop(): void {
  const now = Date.now();

  const length = nextQueue.length;

  for (let i = 0; i < length; ++i) {
    nextQueue[i](now);
  }

  $array.shiftLeft(nextQueue, length);

  for (let i = 0; i < readQueue.length; ++i) {
    readQueue[i](now);
  }
  //   清空 已读的动画队列
  readQueue.length = 0;
  for (let i = 0; i < writeQueue.length; i++) {
    writeQueue[i](now);
  }
  writeQueue.length = 0;

  if (nextQueue.length === 0 && readQueue.length === 0) {
    pendingFrame = false;
  } else {
    raf(frameLoop);
  }
}

// pending 状态
function pendFrame(): void {
  if (!pendingFrame) {
    pendingFrame = true;
    raf(frameLoop);
  }
}
export function nextFrame(fn: Listener): void {
  nextQueue.push(fn);
  pendFrame();
}

export function readFram(fn: Listener): void {
  readQueue.push(fn);
  pendFrame;
}

export function writeFram(fn: Listener): void {
  writeQueue.push(fn);
  pendFrame();
}

export function whenIdle(fn: Listener): void {
  console.log("等待队列中", fn);
  idleQueue.push(fn);
}

export function triggerIdle(): void {
  const now = Date.now();
  const length = idleQueue.length;
  for (let i = 0; i < length; i++) {
    (<any>idleQueue.shift())(now);
    console.log("执行队列", i);
  }
}
